conf = require("../config")
if not conf.metals.enabled then return {} end

return {
  "scalameta/nvim-metals",
  dependencies = {
    "nvim-lua/plenary.nvim",
  },
  ft = { "scala", "sbt", "java" },
  opts = function()
    local metals_config = require("metals").bare_config()

    -- Example of settings
    metals_config.settings = {
      enableSemanticHighlighting = false,
      showImplicitArguments = true,
      excludedPackages = { "akka.actor.typed.javadsl", "com.github.swagger.akka.javadsl" },
    }

    metals_config.init_options.statusBarProvider = "off"

    local has_cmp, cmp_nvim_lsp = pcall(require, "cmp_nvim_lsp")
    local has_blink, blink = pcall(require, "blink.cmp")
    local capabilities = vim.tbl_deep_extend(
      "force",
      {},
      vim.lsp.protocol.make_client_capabilities(),
      has_cmp and cmp_nvim_lsp.default_capabilities() or {},
      has_blink and blink.get_lsp_capabilities() or {}
    )
    metals_config.capabilities = capabilities

    metals_config.on_attach = function(client, bufnr)
      require("metals").setup_dap()

      -- disable folding
      client.server_capabilities.foldingRangeProvider = false

      -- LSP mappings
      function bufopts(desc)
        M = { noremap = true, silent = true, buffer = bufnr }
        M.desc = desc
        return M
      end
      vim.keymap.set('n', 'gD',        vim.lsp.buf.declaration,             bufopts("jump to the declaration"))
      -- vim.keymap.set('n', 'gd',        vim.lsp.buf.definition,              bufopts("jumps to the definition"))
      vim.keymap.set('n', '<space>hh', vim.lsp.buf.hover,                   bufopts("display hover information"))
      -- vim.keymap.set('n', 'gi',        vim.lsp.buf.implementation,          bufopts("list all the implementations"))
      vim.keymap.set('n', '<space>ss',  vim.lsp.buf.signature_help,          bufopts("display signature information"))
      vim.keymap.set('n', '<space>wa', vim.lsp.buf.add_workspace_folder,    bufopts("add the folder at path to the workspace folders"))
      vim.keymap.set('n', '<space>wr', vim.lsp.buf.remove_workspace_folder, bufopts("remove the folder at path from the workspace folders"))
      vim.keymap.set('n', '<space>wl', function()
        print(vim.inspect(vim.lsp.buf.list_workspace_folders()))
      end, bufopts("list workspace folders"))
      vim.keymap.set('n', '<space>D',  vim.lsp.buf.type_definition,         bufopts("jump to the definition of the type"))
      vim.keymap.set('n', '<space>rn', vim.lsp.buf.rename,                  bufopts("rename all references to the symbol"))
      vim.keymap.set('n', '<space>ca', vim.lsp.buf.code_action,             bufopts("select a code action available"))
      -- vim.keymap.set('n', 'gr',        vim.lsp.buf.references,              bufopts("list all the references to the symbol"))
      vim.keymap.set("n", "<space>f", function()
        vim.lsp.buf.format({ async = true })
      end, bufopts("format a buffer"))
    end

    return metals_config
  end,
  config = function(self, metals_config)
    local nvim_metals_group = vim.api.nvim_create_augroup("nvim-metals", { clear = true })
    vim.api.nvim_create_autocmd("FileType", {
      pattern = self.ft,
      callback = function()
        require("metals").initialize_or_attach(metals_config)
      end,
      group = nvim_metals_group,
    })
  end
}
